package com.indusfo.spc.common.utlis;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.log4j.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;


/**
 * @Description: office转pdf.！！使用这个类，需要安装特定的环境文件,目前直接注释掉，以免他人环境问题报错！！
 * @Params:
 * @Returns:
 * @author: 余家能
 * @date: 2018/12/21 上午9:26
 */
public class OfficeToPdf {

    private static Logger logger = Logger.getLogger(OfficeToPdf.class);
    static final int wdFormatPDF = 17;// PDF 格式
    /**
     * word转化为PDF
     * @param sfileName
     * @param toFileName
     * @return
     * @throws Exception
     * @author ygl
     */
    public static int word2Pdf(String sfileName,String toFileName) throws Exception{

        logger.info("启动Word...");
        logger.info(sfileName+",,"+toFileName);
        long start = System.currentTimeMillis();
        ActiveXComponent app = null;
        Dispatch doc = null;
        try {
            app = new ActiveXComponent("Word.Application");
            app.setProperty("Visible", new Variant(false));
            // 打开word文件
            Dispatch docs = app.getProperty("Documents").toDispatch();
//          doc = Dispatch.call(docs,  "Open" , sourceFile).toDispatch();
            doc = Dispatch.invoke(docs,"Open",Dispatch.Method,new Object[] {
                    sfileName, new Variant(false),new Variant(true) }, new int[1]).toDispatch();

            logger.info("打开文档..." + sfileName);
            logger.info("转换文档到PDF..." + toFileName);
            File tofile = new File(toFileName);
            // System.err.println(getDocPageSize(new File(sfileName)));
            if (tofile.exists()) {
                tofile.delete();
            }
//          Dispatch.call(doc, "SaveAs",  destFile,  17);
            // 作为html格式保存到临时文件：：new Variant(8)其中8表示word转html;7表示word转txt;44表示Excel转html;17表示word转成pdf。
            Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] {
                    toFileName, new Variant(17) }, new int[1]);
            long end = System.currentTimeMillis();
            logger.info("转换完成..用时：" + (end - start) + "ms.");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("========Error:文档转换失败：",e);
        }catch(Throwable t){
            t.printStackTrace();
            logger.error("word转换失败",t);
        } finally {
            // 关闭word
            Dispatch.call(doc,"Close",false);
            logger.info("关闭文档");
            if (app != null) {
                app.invoke("Quit", new Variant[] {});
            }
        }
        //如果没有这句winword.exe进程将不会关
        ComThread.Release();
        return 1;
    }
    private static Document read(File xmlFile) throws DocumentException {
        SAXReader saxReader = new SAXReader();
        return saxReader.read(xmlFile);
    }
    public  int getDocPageSize(String filePath)  throws Exception {
        XWPFDocument docx = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        int pages = docx.getProperties().getExtendedProperties().getUnderlyingProperties().getPages();//总页
        int wordCount = docx.getProperties().getExtendedProperties().getUnderlyingProperties().getCharacters();// 忽略空格的字符另外还有getCharactersWithSpaces()方法获取带空格的总字数�?
        System.out.println ("pages=" + pages + " wordCount=" + wordCount);
        return pages;
    }
    /**
     * excle转PDF
     * @param
     * @param
     * @author ygl
     */
    public static void excel2Pdf(String inFilePath, String outFilePath) throws Exception {
        ActiveXComponent ax = null;
        Dispatch excel = null;
        try {
            ComThread.InitSTA();
            ax = new ActiveXComponent("Excel.Application");
            ax.setProperty("Visible", new Variant(false));
            ax.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏
            Dispatch excels = ax.getProperty("Workbooks").toDispatch();
            Object[] obj = new Object[]{
                    inFilePath,
                    new Variant(false),
                    new Variant(false)
            };
            excel = Dispatch.invoke(excels, "Open", Dispatch.Method, obj, new int[9]).toDispatch();
            File tofile = new File(outFilePath);
            // System.err.println(getDocPageSize(new File(sfileName)));
            if (tofile.exists()) {
                tofile.delete();
            }
            // 转换格式
            Object[] obj2 = new Object[]{
                    new Variant(0), // PDF格式=0
                    outFilePath,
                    new Variant(0)  //0=标准 (生成的PDF图片不会变模糊) ; 1=最小文件
            };
            Dispatch.invoke(excel, "ExportAsFixedFormat", Dispatch.Method,obj2, new int[1]);
            logger.info("转换excel完毕！");
        } catch (Exception es) {
            es.printStackTrace();
            throw es;
        } finally {
            if (excel != null) {
                Dispatch.call(excel, "Close", new Variant(false));
            }
            if (ax != null) {
                ax.invoke("Quit", new Variant[] {});
                ax = null;
            }
            ComThread.Release();
        }
    }

    public static void pdf2Image(String PdfFilePath, String imgeFilePath, int dpi) {
        logger.info("pdf转图片开始....");
        long start = System.currentTimeMillis();
        File file = new File(PdfFilePath);
        PDDocument pdDocument;
        try {
                pdDocument = PDDocument.load(file);
                PDFRenderer renderer = new PDFRenderer(pdDocument);
                /* dpi越大转换后越清晰，相对转换速度越慢 */
                int pages = pdDocument.getNumberOfPages();
//                PdfReader reader = new PdfReader(PdfFilePath);
//                int pages = reader.getNumberOfPages();
                for (int i = 0; i < pages; i++) {
                    File dstFile = new File(imgeFilePath);
                    BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                    ImageIO.write(image, "png", dstFile);
                }
                System.out.println("PDF文档转PNG图片成功！");
            long end = System.currentTimeMillis();
            logger.info("转换完成..用时：" + (end - start) + "ms.");

        } catch (IOException e) {
            logger.error("转换图片失败！",e);
            e.printStackTrace();
        }
    }

    private static boolean createDirectory(String folder) {
        File dir = new File(folder);
        if (dir.exists()) {
            return true;
        } else {
            return dir.mkdirs();
        }
    }


    /**
     * @Description: TODO
     * @Params: [inFilePath, outFilePath]
     * @Returns: void
     * @author: 余家能
     * @date: 2018/12/19 下午8:21
     */
    public static void office2Pdf(String inFilePath, String outFilePath){
        try{
            if (inFilePath.endsWith(".doc") || inFilePath.endsWith(".docx")){
                word2Pdf(inFilePath,outFilePath);
            }else if(inFilePath.endsWith(".xlsx") || inFilePath.endsWith(".xls")){
                excel2Pdf(inFilePath,outFilePath);
            }
        }catch (Exception e){
            System.out.println(e);
        }
    }


    public static void main(String[] args) throws Exception {
//
//        String inFilePath ="H://sop/08A.xlsx";
//        String outFilePath = "H://sop/08A.pdf";
//        word2Pdf(inFilePath, outFilePath);
//
//        office2Pdf(inFilePath,outFilePath);

       // excel2Pdf("d:\\44.xlsx", "d:\\44.pdf");


        String pdfpath = "/Users/yujn/Documents/sop1.pdf";
        String imgpath = "/Users/yujn/Documents/sop10000.png";
        pdf2Image(pdfpath,imgpath,1000);

    }

}
